package com.hardy.basic;

import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Author: Hardy
 * Date:   2021/2/20
 * Description:
 **/
public class Demo {
    Lock l;
    Condition cond;



    interface I {
        void t();
    }

    enum Day implements I {
        SATURDAY, SUNDAY;

        @Override
        public void t() {
            System.out.println(SATURDAY);
        }
    }


    public Demo() {
        this.l = new ReentrantLock();
        this.cond = l.newCondition();
    }

    void t1(Map<String, Integer> map) {
        Iterator<Map.Entry<String, Integer>> iterator = map.entrySet().iterator();
        Iterator<Map.Entry<String, Integer>> iterator2 = map.entrySet().iterator();

        while (iterator.hasNext()) {
            Map.Entry<String, Integer> e = iterator.next();
            if (e.getKey().equals("0")) map.put("1", 0);
            map.put(e.getKey(), e.getValue() + 1);
            System.out.println(e.getKey() + " <-> " + e.getValue());
        }

        System.out.println("---------");
        while (iterator2.hasNext()) {
            Map.Entry<String, Integer> e = iterator2.next();
            if (e.getKey().equals("0")) map.remove(e.getKey());
            System.out.println(e.getKey() + " <-> " + e.getValue());
        }
    }

    int t2(ForkJoinPool pool, int n) throws ExecutionException, InterruptedException {
        if (n == 0 || n == 1) return 1;
        return pool.submit(() -> t2(pool, n - 1)).get() + pool.submit(() -> t2(pool, n - 2)).get();
        //return t4(pool, n - 1) + t4(pool, n - 2);
    }

    synchronized void t3(Object o) {
        try {
            System.out.println(1);
            o.wait();
            System.out.println(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    synchronized void t4(Object o) {
        o.notify();
    }

    void t5(Object o) {
        l.lock();
        try {
            System.out.println(1);
            cond.await();
            System.out.println(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        l.unlock();
    }

    void t6(Object o) {
        l.lock();
        cond.signal();
        l.unlock();
    }

    void t7() {
        EnumMap map = new EnumMap<>(Day.class);
        map.put(Day.SATURDAY, 10);

        EnumSet s1 = EnumSet.noneOf(Day.class);
        s1.add(Day.SATURDAY);

        EnumSet s2 = EnumSet.noneOf(Enum.class);
        s1.add(Day.SUNDAY);

        s1.addAll(s2);
        System.out.println(s1);
    }

    void t8() {
        List<Integer> list = Arrays.asList(1, 2, 9, 4, 6, 5);
        Collections.sort(list, (o1, o2) -> o2 - o1);
        System.out.println(Arrays.toString(list.toArray()));
    }

    void print(Map<String, Integer> map) {
        for (String k : map.keySet()) {
            System.out.println(k + " -> " + map.get(k));
        }
    }

    static int test(int ts) {
        sleep(ts);
        return 0;
    }

    static void sleep(int ts) {
        try {
            TimeUnit.SECONDS.sleep(ts);
        } catch (InterruptedException ignored) {
        }
    }

    Map<String, Integer> getMap() {
        Map<String, Integer> map = new ConcurrentHashMap<>();
        for (int i = 0; i < 3; i++) {
            map.put(i + "", i);
        }
        return map;
    }

    public static void main(String[] args) throws InterruptedException, ExecutionException {
        Demo demo = new Demo();
        //Map<String, Integer> map = demo.getMap();
        //demo.t3(map);

        //ForkJoinPool pool = new ForkJoinPool();
        //System.out.println(demo.t2(pool, 3));

        //final ReentrantLock lock = new ReentrantLock();
//        final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
//        ReentrantReadWriteLock.ReadLock rlock = rwLock.readLock();
//        ReentrantReadWriteLock.WriteLock wlock = rwLock.writeLock();
//        rlock.lock();
//
//        Thread t1 = new Thread(() -> {
//            System.out.println("开始 thread read 1");
//            rlock.lock();
//            sleep(3);
//            rlock.unlock();
//            System.out.println("结束 thread read 1");
//        });
//        t1.start();
//
//        Thread t2 = new Thread(() -> {
//            System.out.println("开始 thread write 1");
//            wlock.lock();
//            System.out.println("开始 thread write 1 ...");
//            sleep(3);
//            wlock.unlock();
//            System.out.println("结束 thread write 1");
//
//        });
//        t2.start();
//
//        rlock.unlock();
//
//
//        Thread t3 = new Thread(() -> {
//            System.out.println("开始 thread read 3");
//            rlock.lock();
//            System.out.println("开始 thread read 3 ...");
//            sleep(3);
//            rlock.unlock();
//            System.out.println("结束 thread read 3");
//        });
//        t3.start();
//
//        Thread t4= new Thread(() -> {
//            System.out.println("开始 thread read 4");
//            rlock.lock();
//            System.out.println("开始 thread read 4 ...");
//            sleep(3);
//            rlock.unlock();
//            System.out.println("结束 thread read 4");
//        });
//        t4.start();
//
//        t1.join();
//        t2.join();
//        t3.join();
//        t4.join();
//
//        ThreadLocal<Object> local = new ThreadLocal<>();
//        local.get();
//        local.set("0");
//
//        Arrays.asList(1, 2, 3, 4, 5, 6, 7, 9, 8, 0, 1, 1, 2, 3, 4, 5, 9)
//                .stream()
//                .parallel()
//                .collect(Collectors.groupingBy(x -> {
//                    //控制台查看当前线程
//                    System.out.println(Thread.currentThread().getName());
//                    try {
//                        //执行慢点，方便visualVM上查看线程
//                        Thread.sleep(5000);
//                    } catch (InterruptedException e) {
//                        e.printStackTrace();
//                    }
//                    int i = x % 10;
//                    return i;
//                }))
//                .forEach((x, y) -> System.out.println(x + ":" + y));

        ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1,
                0L, TimeUnit.MILLISECONDS,
                new SynchronousQueue<Runnable>());

        //executor.execute(() -> test(5));

        Future<Integer> future = executor.submit(() -> test(5));
        System.out.println(future.get());

        System.out.println(executor.isTerminated());

    }
}
